import os
from typing import Optional


class PathManager:
    """
    项目路径管理器
    
    负责管理项目中各种目录路径的获取和创建，
    提供统一的路径访问接口，确保目录存在性。
    """

    def __init__(self, base_dir: Optional[str] = None):
        """
        初始化路径管理器
        
        Args:
            base_dir: 项目根目录，如果为None则自动检测
        """
        if base_dir:
            self._base_dir = base_dir
        else:
            self._base_dir = self._detect_project_root()

    def _detect_project_root(self) -> str:
        """
        智能检测项目根目录
        
        Returns:
            str: 项目根目录路径
        """
        # 项目标识文件
        project_markers = [
            'pytest.ini', 'conftest.py',
            'pyproject.toml', 'requirements.txt'
        ]

        # 从当前目录开始向上查找
        current_dir = os.getcwd()
        while current_dir != os.path.dirname(current_dir):  # 直到根目录
            for marker in project_markers:
                if os.path.exists(os.path.join(current_dir, marker)):
                    return current_dir
            current_dir = os.path.dirname(current_dir)

        # 如果没找到，使用当前工作目录
        return os.getcwd()

    @property
    def base_dir(self) -> str:
        """项目根目录"""
        return self._base_dir
    
    @property
    def ini_path(self) -> str:
        """配置文件路径"""
        return os.path.join(self._base_dir, 'config.ini')
    
    @property
    def element_path(self) -> str:
        """页面元素目录"""
        return os.path.join(self._base_dir, 'page_element')
    
    @property
    def page_path(self) -> str:
        """page类目录"""
        return os.path.join(self._base_dir, 'pages')
    
    @property
    def driver_path(self) -> str:
        """Chrome驱动路径"""
        return os.path.join(self._ensure_dir_exists('driver'), 'chromedriver.exe')
    
    @property
    def firefox_driver_path(self) -> str:
        """Firefox驱动路径"""
        return os.path.join(self._ensure_dir_exists('driver'), 'geckodriver.exe')
    
    @property
    def edge_driver_path(self) -> str:
        """Edge驱动路径"""
        return os.path.join(self._ensure_dir_exists('driver'), 'msedgedriver.exe')
    
    @property
    def ie_driver_path(self) -> str:
        """IE驱动路径"""
        return os.path.join(self._ensure_dir_exists('driver'), 'IEDriverServer.exe')

    @property
    def report_dir(self) -> str:
        """测试报告目录"""
        return self._ensure_dir_exists('report')
    
    @property
    def screen_dir(self) -> str:
        """错误截图目录"""
        return self._ensure_dir_exists('screen')
    
    @property
    def test_suites_dir(self) -> str:
        """测试用例目录"""
        return self._ensure_dir_exists('cases')

    @property
    def data_dir(self) -> str:
        """测试数据目录"""
        return self._ensure_dir_exists('data')

    @property
    def logs_dir(self) -> str:
        """日志目录"""
        return self._ensure_dir_exists('logs')
    
    @property
    def log_path(self):
        """日志目录路径"""
        return self.logs_dir
    
    @property
    def report_path(self):
        """报告文件路径"""
        from utils.times import strftime
        return os.path.join(self.report_dir, '{}.html'.format(strftime()))
    
    @property
    def data_path(self):
        """测试数据目录路径"""
        return self.data_dir
    
    @property
    def screen_path(self):
        """错误截图目录路径"""
        return self.screen_dir
        
    @property
    def explicitly_wait_time(self):
        """显式等待时间"""
        return 10
    
    @property
    def retry_max_attempts(self):
        """重试装饰器默认最大尝试次数"""
        return 3
    
    @property
    def retry_delay(self):
        """重试装饰器默认延迟时间（秒）"""
        return 0.5
    
    @property
    def retry_backoff(self):
        """重试装饰器默认延迟时间增长因子"""
        return 2


    def _ensure_dir_exists(self, dir_name: str) -> str:
        """
        确保目录存在，如果不存在则创建
        
        Args:
            dir_name: 目录名称
            
        Returns:
            str: 目录的完整路径
        """
        dir_path = os.path.join(self._base_dir, dir_name)
        if not os.path.exists(dir_path):
            os.makedirs(dir_path, exist_ok=True)
        return dir_path

    def get_custom_dir(self, dir_name: str, ensure_exists: bool = True) -> str:
        """
        获取自定义目录路径
        
        Args:
            dir_name: 目录名称
            ensure_exists: 是否确保目录存在
            
        Returns:
            str: 目录的完整路径
        """
        if ensure_exists:
            return self._ensure_dir_exists(dir_name)
        return os.path.join(self._base_dir, dir_name)

    def get_file_path(self, dir_name: str, filename: str) -> str:
        """
        获取文件的完整路径
        
        Args:
            dir_name: 目录名称
            filename: 文件名
            
        Returns:
            str: 文件的完整路径
        """
        return os.path.join(self._ensure_dir_exists(dir_name), filename)


# 全局路径管理器实例
path_manager = PathManager()